package nameless.aistudy.domain.service.user.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import nameless.aistudy.common.enumeration.request.RequestAttributeNameEnum;
import nameless.aistudy.common.enumeration.user.RoleEnum;
import nameless.aistudy.common.exception.BusinessException;
import nameless.aistudy.domain.model.user.User;
import nameless.aistudy.domain.model.user.UserRepo;
import nameless.aistudy.domain.service.user.UserAuthService;
import nameless.aistudy.domain.service.user.dto.RegisterRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import static nameless.aistudy.common.enumeration.message.MessageEnum.*;

@Service
public class UserServiceImpl extends ServiceImpl<UserRepo, User> implements UserAuthService {

    // 使用Map模拟存储验证码（后续尝试改用Redis）
    private final Map<String, String> codeMap = new HashMap<>();

    @Override
    public int getUserIdFromRequest(HttpServletRequest request) {
        return (int) request.getAttribute(RequestAttributeNameEnum.USER_ID.name);
    }

    @Override
    public boolean register(RegisterRequest registerRequest) {

        User user = new User();
        BeanUtils.copyProperties(registerRequest, user);
        
        String username = registerRequest.getUsername();

        if (username.isEmpty()) {
            throw new BusinessException(INVALID_FORMAT_USERNAME.getMessage() + "："
                    + INVALID_FORMAT_BEING_EMPTY.getMessage()
            );
        }
        if (!username.equals(username.trim())) {
            throw new BusinessException(INVALID_FORMAT_USERNAME.getMessage() + "："
                    + INVALID_FORMAT_WITH_WHITE_SPACE_AROUND.getMessage()
            );
        }
        if (username.matches("^\\d+$")) {
            throw new BusinessException(INVALID_FORMAT_USERNAME.getMessage() + "："
                    + INVALID_FORMAT_WITH_ALL_NUMBER.getMessage()
            );
        }

        verifyCode(registerRequest.getPhone(), registerRequest.getVerificationCode());

        // 检查用户名和手机号是否已存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username)
                .or()
                .eq(User::getPhone, registerRequest.getPhone());

        if (count(queryWrapper) > 0) {
            throw new BusinessException(USER_OR_PHONE_ALREADY_EXIST.getMessage());
        }

        // 设置默认角色为普通用户
        user.setRole(Long.valueOf(RoleEnum.USER.getId()).intValue());
        // 密码加密
        user.setPassword(encryptPassword(registerRequest.getPassword()));
        return save(user);
    }

    @Override
    public User login(String usernameOrPhone, String password) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, usernameOrPhone)
                .or().eq(User::getPhone, usernameOrPhone);

        User user = getOne(queryWrapper);
        if (user == null) {
            throw new BusinessException(USER_DOESNT_EXIST.getMessage());
        }

        // 验证密码（实际项目中使用BCrypt等加密方式）
        if (!user.getPassword().equals(encryptPassword(password))) {
            throw new BusinessException(INVALID_PASSWORD.getMessage());
        }

        return user;
    }

    @Override
    public boolean sendVerificationCode(String phone) throws BusinessException {
        if (!phone.matches("^\\d{11}$")) {
            throw new BusinessException(INVALID_FORMAT_PHONE.getMessage()
                    + "：" + NON_DIGIT_PHONE.getMessage());
        }

        // 检查手机号是否已注册
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, phone);

        if (count(queryWrapper) > 0) {
            throw new BusinessException(PHONE_ALREADY_REGISTERED.getMessage());
        }

        // 生成6位随机验证码
        String code = String.format("%06d", new Random().nextInt(1000000));
        // 存储验证码（实际项目中应使用Redis，并设置过期时间）
        codeMap.put(phone, code);

        // 后续改为调用短信服务发送验证码
        System.out.println("验证码已发送到手机号" + ": " + phone + ", 验证码: " + code);

        return true;
    }

    public boolean verifyCode(String phone, String code) {
        String storedCode = codeMap.get(phone);
        if (storedCode == null || !storedCode.equals(code)) {
            throw new BusinessException(INVALID_OR_EXPIRED_CODE.getMessage());
        }

        // 验证成功后删除验证码
        codeMap.remove(phone);
        return true;
    }

    // 密码加密（后续使用BCrypt等加密方式）
    private String encryptPassword(String password) {
        return "encrypted_" + password;
    }
}

